#ifndef __CONNECTPOOL_H__
#define __CONNECTPOOL_H__

#include "mysqlDataBase.h"
#include <memory> // 智能指针
#include <queue>  // 队列
#include <string>
#include <mutex> // 锁
#include <condition_variable> // 条件变量
#include <thread> // 线程

class ConnectPool
{
public:
    // 提供一个静态方法，让外部调用唯一实例
    static ConnectPool *getConnectPool();
    // 删除拷贝构造
    ConnectPool(const ConnectPool &obj) = delete;
    // 删除赋值
    ConnectPool &operator=(const ConnectPool &obj) = delete;
    // 析构
    ~ConnectPool();

public:
    // 从连接池中取出一个MySql连接
    std::shared_ptr<MySqlDataBase> getConnection();

private:
    // 构造函数私有化（写成单例需要将构造私有）
    ConnectPool();
    // 添加连接到连接池中
    bool addConnection();
    // 生产线程入口（向数据库来凝结吃生产连接句柄）
    void produceConnection();
    // 回收线程入口（回收数据库连接池的连接）
    void recycleConnection();
    // 解析配置文件（config.json）
    bool parseConfigFile(const std::string &path);

private:
    // 连接池内部维护的数据库连接句柄
    std::queue<MySqlDataBase *> m_connectQueue;

    // 锁
    std::mutex m_mutex;
    // 条件变量
    std::condition_variable m_cond_produce; // 生产者条件变量（连接池连接不够的时候）
    std::condition_variable m_cond_consume; // 消费者条件变量（连接池有多余连接的时候）

    // 配置文件的私有属性
    std::string m_hostname;
    std::string m_username;
    std::string m_passwd;
    int m_port;
    std::string m_dbname;
    int m_minSize;
    int m_maxSize;
    int m_maxIdleTime;
};

#endif // __CONNECTPOOL_H__